package com.github.chain.admin.server.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.github.chain.admin.common.domain.Role;
import com.github.chain.admin.common.domain.User;
import com.github.chain.admin.common.domain.UserRole;
import com.github.chain.admin.common.enums.AdminErrorMsgEnum;
import com.github.chain.admin.common.request.UserRequest;
import com.github.chain.admin.common.utils.ShiroUtil;
import com.github.chain.admin.server.dao.RoleDao;
import com.github.chain.admin.server.dao.UserDao;
import com.github.chain.admin.server.dao.UserRoleDao;
import com.github.chain.admin.server.service.UserService;
import com.github.framework.core.Result;
import com.github.framework.core.exception.Ex;
import com.github.framework.core.page.DataPage;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {

    private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);

    @Resource
    private UserDao userDao;

    @Resource
    private UserRoleDao userRoleDao;

    @Resource
    private RoleDao roleDao;

    @Override
    public Result<User> findUserByUserName(String userName) {

        LOGGER.info("根据用户名称查询用户信息,用户名称:userName{}",userName);
        if (StringUtils.isBlank(userName)){
            LOGGER.error("当前用户请求用户名为空");
            return Result.fail(AdminErrorMsgEnum.REQUEST_PARAMS_IS_EMPTY);
        }

        User user = userDao.findUserByUserName(userName);

        if (user == null){
            LOGGER.error("当前用户不存在,请求用户名称:userName:{}",userName);
            return Result.fail(AdminErrorMsgEnum.CURRENT_USER_NOT_EXIST);
        }

        LOGGER.info("查询用户信息成功,userName{}，nickName:{}",user.getUserName(),user.getNickName());

        return Result.ok(user);
    }

    @Override
    public Result<DataPage<User>> findUserByPage(UserRequest userRequest) {

        Integer pageNo = userRequest.getPageNo();
        Integer pageSize = userRequest.getPageSize();

        LOGGER.info("从第{}页开始, 显示{}条", pageNo, pageSize);

        DataPage<User> dataPage = new DataPage<>(pageNo, pageSize);
        Map<String, Object> map = BeanUtil.beanToMap(userRequest);
        map.put("start", dataPage.getStartIndex());
        map.put("offset", dataPage.getPageSize());

        long userCount = userDao.findUserCountByPage(map);
        List<User> list = userDao.findUserListByPage(map);

        LOGGER.info("查询用户大小数量TotalCount:{}", userCount);

        dataPage.setTotalCount(userCount);
        dataPage.setDataList(list);

        return Result.ok(dataPage);
    }


    @Override
    public Result<User> findUserById(Long id) {
        if (id == null){
            LOGGER.error("当前传入的userId:{}为空",id);
            return Result.fail(AdminErrorMsgEnum.REQUEST_PARAMS_IS_EMPTY);
        }

        User user = userDao.findUserByUserId(id);

        if (user == null){
            LOGGER.error("当前用户不存在,请求用户Id:userId{}",id);
            return Result.fail(AdminErrorMsgEnum.CURRENT_USER_NOT_EXIST);
        }

        LOGGER.info("查询用户成功,userName:{},nickName:{}",user.getUserName(),user.getNickName());

        return Result.ok(user);
    }

    @Override
    public Result<Integer> saveUser(UserRequest userRequest)  {
        User user = new User();
        BeanUtils.copyProperties(userRequest, user);

        Date date = new Date();
        user.setCreateDate(date);

        String password = userRequest.getPassword();
        String confirm = userRequest.getConfirm();
        String userName = userRequest.getUserName();

        LOGGER.error("密码:{}，确认密码:{}", password, confirm);

        if (StringUtils.isBlank(password) || StringUtils.isBlank(confirm)){

            LOGGER.error("用户输入密码或确认密码为空");
            return Result.fail(AdminErrorMsgEnum.REQUEST_PARAMS_IS_EMPTY);
        }

        if (!StringUtils.equals(password, confirm)){

            LOGGER.error("用户输入密码或者确认密码不一致, password:{}, confirm: {}", password, confirm);
            return Result.fail(AdminErrorMsgEnum.CURRENT_USER_PASSWORD_IS_NOT_SAME);
        }

        int len = userName.length();
        int trimLen = userName.trim().length();
        if (len != trimLen){

            LOGGER.error("当期用户输入空格, 原长度为:{}，去掉空格长度为:{}", password, confirm);
            return Result.fail(AdminErrorMsgEnum.CURRENT_USER_IS_EXIST_BANK);
        }

        User existUser = userDao.findUserByUserName(userName);
        if (existUser != null && StringUtils.equals(existUser.getUserName().trim(), userName.trim())){
            LOGGER.error("当期用户已存在,userName:{}", userName);
            return Result.fail(AdminErrorMsgEnum.CURRENT_USER_IS_EXIST);
        }

        String salt = ShiroUtil.getRandomSalt();
        String pwd = ShiroUtil.encrypt(userRequest.getPassword(), salt);
        user.setPassword(pwd);
        user.setSalt(salt);
        Integer status = userDao.insertSelective(user);

        if (status != 1){

            LOGGER.error("添加用户失败，返回状态status:{}", status);
            return Result.fail(AdminErrorMsgEnum.CURRENT_USER_OPERATION_FAIL);
        }

        // TODO 待加自动添加用户组，因为现在添加用户后不能直接登录，需要添加用户组才能登录，需要修改数据库的sys_user_role表
        LOGGER.info("添加成功");

        return Result.ok(status, "00000000", "添加成功");
    }

    @Override
    public Result<Integer> updateUser(UserRequest userRequest) {
        if (userRequest.getId() == null){
            LOGGER.error("修改用户信息id参数为空");
            return Result.fail(AdminErrorMsgEnum.REQUEST_PARAMS_IS_EMPTY);
        }

        Long userId = userRequest.getId();
        User user = userDao.findUserByUserId(userId);
        if (user == null){
            LOGGER.error("当前修改用户不存在, userId:{}", userId);
            return Result.fail(AdminErrorMsgEnum.CURRENT_MENU_NOT_EXIST);
        }

        User updateUser = new User();
        BeanUtils.copyProperties(userRequest, updateUser);

        LOGGER.error("哈哈哈哈哈哈哈哈哈或：{}", String.valueOf(updateUser));

        Integer status = userDao.updateSelective(updateUser);
        if (status != 1){
            LOGGER.error("更新用户失败,userId:{}", userId);
            return Result.fail(AdminErrorMsgEnum.CURRENT_USER_OPERATION_FAIL);
        }
        return Result.ok(status);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result deleteUserById(Long id) {

        if(id == null){
            LOGGER.error("删除用户数据请求id为空");
            return Result.fail(AdminErrorMsgEnum.REQUEST_PARAMS_IS_EMPTY);
        }

        Integer deleteUserStatus = userDao.deleteUserById(id);

        if (deleteUserStatus != 1){
            LOGGER.error("用户id:{}删除数据失败", id);

        }

        //Integer deleteUserRoleByUserId = userRoleDao.deleteUserRoleByUserId(id);

        return Result.ok(deleteUserStatus);
    }

    @Override
    public Result<Integer> enableUserStatus(List<Long> ids) {

        if (CollectionUtils.isEmpty(ids)){
            LOGGER.error("修改用户启用状态参数为空");
            return Result.fail(AdminErrorMsgEnum.REQUEST_PARAMS_IS_EMPTY);
        }

        Integer status = userDao.updateUSerStatusById(ids, 1);

        if (status <= 0){
            return Result.fail(AdminErrorMsgEnum.CURRENT_USER_OPERATION_FAIL);
        }

        LOGGER.info("修改用户启用状态成功ids: {}", ids);

        return Result.ok(status);
    }

    @Override
    public Result<Integer> disableUserStatus(List<Long> ids) {

        if (CollectionUtils.isEmpty(ids)){
            LOGGER.error("修改用户停用状态参数为空");
            return Result.fail(AdminErrorMsgEnum.REQUEST_PARAMS_IS_EMPTY);
        }

        Integer status = userDao.updateUSerStatusById(ids, 2);

        if (status <= 0){
            return Result.fail(AdminErrorMsgEnum.CURRENT_USER_OPERATION_FAIL);
        }

        LOGGER.info("修改用户停用状态成功ids: {}", ids);

        return Result.ok(status);
    }

    @Override
    public Result<Integer> modifyUserPassword(UserRequest userRequest) {

        if (userRequest == null || userRequest.getId() == null){
            LOGGER.error("修改用户密码请求为空");
            return Result.fail(AdminErrorMsgEnum.REQUEST_PARAMS_IS_EMPTY);
        }

        String password = userRequest.getPassword();
        String confirm = userRequest.getConfirm();
        if (StringUtils.isBlank(password) || StringUtils.isBlank(confirm)){
            LOGGER.error("修改用户密码请求参数密码或确认密码为空, password:{}, confirm{}", password, confirm);
            return Result.fail(AdminErrorMsgEnum.REQUEST_PARAMS_IS_EMPTY);
        }

        if (!StringUtils.equals(confirm, password)){

            LOGGER.error("修改用户密码输入密码和确认密码不一致, password:{}, confirm:{}", password, confirm);
            return Result.fail(AdminErrorMsgEnum.CURRENT_USER_PASSWORD_IS_NOT_SAME);
        }

        Long id = userRequest.getId();

        User user = userDao.findUserByUserId(id);
        if (user == null || user.getStatus() == 2){
            LOGGER.error("当前用户不存在或已停用， id:{}", id);
            return Result.fail(AdminErrorMsgEnum.CURRENT_USER_NOT_EXIST);
        }


        User modifyUser = new User();
        String salt = ShiroUtil.getRandomSalt();
        String pwd = ShiroUtil.encrypt(password, salt);

        modifyUser.setUpdateDate(new Date());
        modifyUser.setId(id);
        modifyUser.setPassword(pwd);
        modifyUser.setSalt(salt);

        Integer status = userDao.updateSelective(modifyUser);
        if (status != 1){
            LOGGER.error("修改用户密码失败,id:{}, 修改返回status:{}", id, status);
            return Result.fail(AdminErrorMsgEnum.CURRENT_USER_OPERATION_FAIL);
        }

        return Result.ok(status);
    }

    @Override
    public Result<User> roleAssignmentById(Long id) {

        if (id == null){
            LOGGER.error("角色分配参数为空");
            return Result.fail(AdminErrorMsgEnum.REQUEST_PARAMS_IS_EMPTY);
        }

        User existUser = userDao.findUserByUserId(id);
        if (existUser == null || existUser.getStatus() == 2){
            LOGGER.error("当前用户不存在或已停用， id:{}", id);
            return Result.fail(AdminErrorMsgEnum.CURRENT_USER_NOT_EXIST);
        }

        List<UserRole> userRoleList = userRoleDao.findUserRoleByUserId(id);
        List<Role> roleList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(userRoleList)){
            LOGGER.error("当前用户id :{} 查询对应的用户角色数据为空", id);

            List<Long> roleIds = new ArrayList<>();
            userRoleList.stream().forEach(userRole -> {
                roleIds.add(userRole.getRoleId());
            });

            LOGGER.info("角色分配用户角色获取到角色集合数据roleIds:{}", roleIds);
            roleList = roleDao.findRoleByRoleIds(roleIds);
        }



        // 查询所有角色
        List<Role> allRoles = roleDao.findRoleByRoleIds(null);
        //Set<Role> set = new HashSet<>();

        if (CollectionUtils.isEmpty(allRoles)){
            LOGGER.error("角色分配查询用户对应的具体角色数据为空或者角色集合数据不存在, userId:{} ", id);
            return Result.fail(AdminErrorMsgEnum.CURRENT_USER_ROLE_NOT_EXIST);
        }

        Set<Role> set = roleList.stream().filter(role -> role.getStatus() == 1).collect(Collectors.toSet());
        List<Role> list = allRoles.stream().filter(role -> role.getStatus() == 1).collect(Collectors.toList());
        existUser.setAuthSet(set);
        existUser.setList(list);

        LOGGER.error("角色分配id:{} 查询对应授权角色set：{}， 全部角色list:{}", id, set, list);

        return Result.ok(existUser);
    }

    @Override
    public Result<Integer> authUserRole(UserRequest userRequest) {

        if (null == userRequest.getId()){
            LOGGER.error("角色分配授权请求参数为空");
            return Result.fail(AdminErrorMsgEnum.REQUEST_PARAMS_IS_EMPTY);
        }

        Long id = userRequest.getId();
        User user = userDao.findUserByUserId(id);

        if (user == null || user.getStatus() == 2){
            LOGGER.error("当前用户不存在或已停用， id:{}", id);
            return Result.fail(AdminErrorMsgEnum.CURRENT_USER_NOT_EXIST);
        }

        Integer delUserRoleStatus = userRoleDao.deleteUserRoleByUserId(id);
        LOGGER.info("角色分配授权删除用户角色数据状态delUserRoleStatus:{}", delUserRoleStatus);
        List<Long> roleIds = userRequest.getRoleIds();
        Integer status = 0;
        if(CollectionUtils.isEmpty(roleIds)) {
            return Result.ok(status);
        }
        for (Long roleId : roleIds){
            UserRole userRole = new UserRole();
            userRole.setRoleId(roleId);
            userRole.setUserId(id);

            status = userRoleDao.insertSelective(userRole);
            if (status != 1){
                throw Ex.business(AdminErrorMsgEnum.DATABASE_OPTION_EXCEPTION);
            }
        }


        return Result.ok(status);
    }


}
